package com.qingcheng.common;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qingcheng.entity.PageResult;
import com.qingcheng.exception.BusinessException;
import com.qingcheng.pojo.goods.Brand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.List;

/**
 * T是实体类
 * pK是主键类型
 * R是DAO层
 *
 * @author jia lin
 * @Date 2019-05-23
 */
public abstract class BaseServiceImpl<T, PK extends Serializable, R extends BaseDao<T, PK>> implements BaseService<T, PK> {
    @Autowired
    private R baseDao;


    @Override
    public T findById(PK id) {
        return baseDao.selectByPrimaryKey(id);
    }

    @Override
    public void delete(PK id) {
        baseDao.deleteByPrimaryKey(id);
    }

    @Override
    public List<T> findAll() {
        return baseDao.selectAll();
    }

    @Override
    public PageResult<T> findPage(int page, int size) {
        PageHelper.startPage(page, size);
        Page<T> pageResult = (Page<T>) baseDao.selectAll();
        return new PageResult<T>(pageResult.getTotal(), pageResult.getResult());
    }

    @Override
    public void add(T brand) {
        baseDao.insertSelective(brand);
    }

    @Override
    public void update(T brand) {
        baseDao.updateByPrimaryKey(brand);
    }

    @Override
    public List<T> findList(T baseEntity) {
        Example example = whereAllIfColumns(baseEntity);
        return baseDao.selectByExample(example);
    }

    @Override
    public PageResult<T> findPage(T baseEntity, int page, int size) {
        if (page != 0 && size != 0) {
            //分页查询
            PageHelper.startPage(page, size);
            //反射去创建查询条件
            Example example = whereAllIfColumns(baseEntity);
            Page<T> pageResult = (Page<T>) baseDao.selectByExample(example);
            return new PageResult<>(pageResult.getTotal(), pageResult.getResult());
        }
        throw new BusinessException("分页数据不正确");
    }

    /**
     * 获取条件字段,模糊查询
     */
    private Example whereAllIfColumns(T object) {
        Example example = new Example(Brand.class);
        Example.Criteria criteria = example.createCriteria();
        Class<?> clz = object.getClass();
        Field[] fields = clz.getDeclaredFields();
        for (Field field : fields) {
            Object value = getFieldValueByName(field.getName(), object);
            if (!StringUtils.isEmpty(value) && !"id".equals(field.getName())) {
                switch (field.getGenericType().toString()) {
                    case "class java.lang.String": {
                        criteria.andLike(field.getName(), "%" + value + "%");
                        break;
                    }
                    case "class java.lang.Integer": {
                        criteria.andLike(field.getName(), "%" + Integer.parseInt((String) value) + "%");
                        break;
                    }
                    case "class java.lang.Long": {
                        criteria.andLike(field.getName(), "%" + Long.parseLong((String) value) + "%");
                        break;
                    }
                    case "class java.util.Date": {
                        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss ");
                        dateTimeFormatter.format((TemporalAccessor) value);
                    }
                }
            }
        }
        return example;
    }

    /**
     * 获取对象属性对应的值
     */
    private Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            return method.invoke(o, new Object[]{});
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * set （目前用不到）
     *
     * @param baseEntity
     * @param fieldName
     * @param o
     */
    private void setFieldValueByName(T baseEntity, String fieldName, Object o) {
        try {
            String setter = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            Method method = o.getClass().getMethod(setter, new Class[]{});
            Object value = method.invoke(baseEntity, o);
        } catch (Exception ignored) {
        }
    }
}
